package com.eascs.workflow.wf.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.eascs.app.dao.PageResult;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.common.util.StringUtil;
import com.eascs.site.controller.BaseRestController;
import com.eascs.site.view.BaseRestResult;
import com.eascs.site.view.HtmlRestResult;
import com.eascs.site.view.ViewContext;
import com.eascs.web.sso.User;
import com.eascs.web.sso.UserHolder;
import com.eascs.workflow.common.entity.sys.ActOrgEntity;
import com.eascs.workflow.common.entity.sys.SysRole;
import com.eascs.workflow.common.entity.wf.ProcessNodeTemplate;
import com.eascs.workflow.common.entity.wf.ProcessTaskMain;
import com.eascs.workflow.common.entity.wf.ProcessTemplate;
import com.eascs.workflow.common.vo.ModelResult;
import com.eascs.workflow.common.vo.NodeApprovalVo;
import com.eascs.workflow.common.vo.UserTaskParam;
import com.eascs.workflow.common.vo.UserTaskVo;
import com.eascs.workflow.sys.service.SysPermissionServiceInlet;
import com.eascs.workflow.wf.dao.ProcessNodeTemplateDao;
import com.eascs.workflow.wf.dao.ProcessTemplateDao;
import com.eascs.workflow.wf.form.NodeApprovalAgreeForm;
import com.eascs.workflow.wf.form.NodeApprovalForm;
import com.eascs.workflow.wf.form.ProcessNodeTemplateForm;
import com.eascs.workflow.wf.form.ProcessTemplateForm;
import com.eascs.workflow.wf.form.SearchOperatorParam;
import com.eascs.workflow.wf.service.TemplateService;
import com.eascs.workflow.wf.service.WFProcessService;
import com.eascs.workflow.wf.service.WFQueryService;
import com.eascs.workflow.wf.vo.TransferNodeParam;

@RestController
public class WorkFlowRestController extends BaseRestController {
	private static Logger logger = LoggerFactory.getLogger(WorkFlowRestController.class);

	@Autowired
	private WFProcessService wfService;
	@Autowired
	private TemplateService templateService;

	@Autowired
	private ProcessTemplateDao processTemplateDao;
	@Autowired
	private ProcessNodeTemplateDao processNodeTemplateDao;

	@Autowired
	private SysPermissionServiceInlet sysPermissionServiceInlet;

	@Value("${o2o.admin.queryTask.url}")
	private String queryTaskURL;

	@Autowired
	private WFQueryService wfQueryService;

	/**
	 * 获取待办列表，给EA门户网提供信息 JSONP方式调用
	 * 
	 * @param userNo
	 * @return
	 */
	@RequestMapping(value = "/o2o/undoList")
	public BaseRestResult<Map<String, String>> getUndoList(String userNo, String jsonpcallback,
			HttpServletResponse response) {
		Map<String, String> undoMap = new HashMap<String, String>();
		try {
			if (StringUtils.isNotBlank(userNo)) {
				UserTaskParam userTaskParam = new UserTaskParam();
				userTaskParam.setApprovalStatus(UserTaskParam.APPROVAL_STATUS_UNDO);
				userTaskParam.setAuditorNo(userNo);
				userTaskParam.setPageIndex(0);
				userTaskParam.setPageSize(1000);
				ModelResult<PageResult<UserTaskVo>> modelResult = wfQueryService.queryUserTaskByPage(userTaskParam);
				if (!modelResult.isSuccess()) {
					logger.info("用户：[{}],查询待办失败:errMsg:[{}]", userNo, modelResult.getErrMsg());
					undoMap.put("undoCount", "0");
					undoMap.put("undoHref", queryTaskURL + "?approvalStatus=UNDO");
				} else {
					int row = modelResult.getModel().getDbRowCount();
					undoMap.put("undoCount", String.valueOf(row));
					undoMap.put("undoHref", queryTaskURL + "?approvalStatus=UNDO");
				}
			} else {
				undoMap.put("undoCount", "0");
				undoMap.put("undoHref", queryTaskURL + "?approvalStatus=UNDO");
			}
			return BaseRestResult.buildRestResult(undoMap);
		} catch (Exception e) {
			undoMap.put("undoCount", "0");
			undoMap.put("undoHref", queryTaskURL + "?approvalStatus=UNDO");
			return BaseRestResult.buildRestResult(undoMap);
		}
	}

	/**
	 * 根据referId查询流程节点，生成审批栏页面
	 * 
	 * @param referId
	 * @return
	 */
	@RequestMapping(value = "/wf/processNode/approval", method = RequestMethod.GET)
	public HtmlRestResult approval(NodeApprovalForm nodeApprovalForm) {
		User user = UserHolder.getUser();
		String nodeAuditorId = nodeApprovalForm.getNodeAuditorId();
		// 查询当前流程审批信息，包括节点处理人权限控制
		NodeApprovalVo nodeApprovalVo = wfQueryService.queryApprovalInfo(user, nodeAuditorId).getModel();
		ViewContext.put("nodeApprovalInfo", nodeApprovalVo);
		ViewContext.put("loadServiceUrl", nodeApprovalForm.getLoadServiceUrl());
		ViewContext.put("user", user);
		return HtmlRestResult.html("/wf/processNode/approval");
	}

	/**
	 * 流程审批意见列表,贷款详情中进来不会有nodeAuditorId
	 * 
	 * @param nodeApprovalForm
	 * @return
	 */
	@RequestMapping(value = "/wf/processNode/agreeList", method = RequestMethod.GET)
	public HtmlRestResult agreeList(NodeApprovalAgreeForm formParam) {
		String nodeAuditorId = formParam.getNodeAuditorId();
		String taskId = "";
		if (StringUtil.hasText(nodeAuditorId)) {
			taskId = wfQueryService.queryTaskIdByNodeAuditorId(nodeAuditorId).getModel();
			ViewContext.put("taskId", taskId);
		}
		String referId = formParam.getReferId();
		ModelResult<List<ProcessTaskMain>> modelResult = wfQueryService.queryAgreeList(referId);
		if (modelResult.isSuccess()) {
			List<ProcessTaskMain> taskMainList = modelResult.getModel();
			ViewContext.put("referId", referId);
			ViewContext.put("taskMainList", taskMainList);
		} else {
			logger.error("获取贷款单审批意见失败，errorMsg:{}", modelResult.getErrMsg());
		}
		return HtmlRestResult.html("/wf/processNode/agreeList");
	}

	/**
	 * 查询节点审批意见
	 * 
	 * @param referId
	 * @param taskId
	 * @return
	 */
	@RequestMapping("/wf/processNode/agreeInfo")
	public HtmlRestResult agreeInfo(String referId, String processType) {
		try {
			ModelResult<ProcessTaskMain> result = wfQueryService.queryAgreeDetail(referId, processType);
			if (result.isSuccess()) {
				ProcessTaskMain taskMain = result.getModel();
				ViewContext.put("taskMain", taskMain);
			} else {
				logger.error("获取贷款单审批意见失败，errorMsg:{}", result.getErrMsg());
			}
		} catch (Exception e) {
			logger.error("query error", e);
		}
		return HtmlRestResult.html("/wf/processNode/agreeInfo");
	}

	@RequestMapping("/wf/processNode/nodeList")
	public HtmlRestResult agreeInfo(String taskId) {
		try {
			ModelResult<ProcessTaskMain> result = wfQueryService.queryAgreeDetailWithTaskId(taskId);
			if (result.isSuccess()) {
				ProcessTaskMain taskMain = result.getModel();
				ViewContext.put("taskMain", taskMain);
			} else {
				logger.error("获取贷款单审批意见失败，errorMsg:{}", result.getErrMsg());
			}
		} catch (Exception e) {
			logger.error("query error", e);
		}
		return HtmlRestResult.html("/wf/processNode/agreeInfo");
	}
	
	/**
	 * 意见审核
	 * 
	 * @param nodeAuditorForm
	 * @return
	 */
	@RequestMapping(value = "/wf/processAction/approval")
	public BaseRestResult<String> approval(TransferNodeParam transferNodeParam) {
		int actionId = transferNodeParam.getActionId();
		if (TransferNodeParam.ACTION_SIGN == actionId && StringUtil.isNull(transferNodeParam.getAdderId())) {
			return BaseRestResult.warn("请选择加签人！");
		}
		if (TransferNodeParam.ACTION_CHANGE == actionId && StringUtil.isNull(transferNodeParam.getAdderId())) {
			return BaseRestResult.warn("请选择转交人！");
		}
		ModelResult<Boolean> modelResult = wfService.transferNodeWithAuto(transferNodeParam);
		if (modelResult.isSuccess()) {
			logger.info("节点处理人ID:{}，提交意见成果", transferNodeParam.getNodeAuditorId());
			return BaseRestResult.info("操作成功").andRefresh();
		} else {
			logger.error("节点处理人ID:{}，提交意见失败，errMsg:{}", transferNodeParam.getNodeAuditorId(), modelResult.getErrMsg());
			return BaseRestResult.warn(modelResult.getErrMsg());
		}
	}

	/**
	 * 联想
	 * 
	 * @param o2oSearchOperator
	 * @return
	 */
	@RequestMapping(value = "/wf/processAction/operator")
	public BaseRestResult<List<Object[]>> searchOperator(SearchOperatorParam searchParam) {
		ModelResult<List<Object[]>> modelResult = new ModelResult<>();
		if (StringUtil.hasText(searchParam.getName())) {
			modelResult = sysPermissionServiceInlet.getOperatorList(searchParam.getName());
			return BaseRestResult.buildRestResult(modelResult.getModel());
		}
		return null;
	}

	@RequestMapping("/process/template/save")
	public BaseRestResult<String> saveUserRole(ProcessTemplateForm processTemplateForm) {
		User user = UserHolder.getUser();
		// 添加
		if (StringUtils.isBlank(processTemplateForm.getProcessNo())) {
			ProcessTemplate processTemplate = new ProcessTemplate();
			try {
				BeanUtils.copyProperties(processTemplate, processTemplateForm);
			} catch (Exception e) {
				return BaseRestResult.warn("保存失败!");
			}
			try {
				processTemplate.setPublishStatus(ProcessTemplate.PUBLISH_STATUS_NO);
				processTemplate.setCreator(user.getNo());
				processTemplate.setCreateTime(new Date());
				processTemplate.setIsDel(0);
				ProcessTemplate saveTemplate = processTemplateDao.insert(processTemplate);
				if (saveTemplate == null) {
					return BaseRestResult.warn("保存失败!");
				}
				ProcessNodeTemplate startNodeTmp = new ProcessNodeTemplate();
				startNodeTmp.setProcessNo(saveTemplate.getProcessNo());
				startNodeTmp.setNodeName("开始节点");
				startNodeTmp.setNodeDesc("开始节点");
				startNodeTmp.setNodeType(ProcessNodeTemplate.NODE_TYPE_INIT);
				startNodeTmp.setOrderNo(1);
				startNodeTmp.setCreatTime(new Date());
				startNodeTmp.setCreator(user.getNo());
				ProcessNodeTemplate endNodeTmp = new ProcessNodeTemplate();
				endNodeTmp.setProcessNo(saveTemplate.getProcessNo());
				endNodeTmp.setNodeName("结束节点");
				endNodeTmp.setNodeDesc("结束节点");
				endNodeTmp.setNodeType(ProcessNodeTemplate.NODE_TYPE_END);
				endNodeTmp.setOrderNo(99);
				endNodeTmp.setCreatTime(new Date());
				endNodeTmp.setCreator(user.getNo());
				processNodeTemplateDao.insert(startNodeTmp);
				processNodeTemplateDao.insert(endNodeTmp);
			} catch (Exception e) {
				return BaseRestResult.warn("保存失败!");
			}
			return BaseRestResult.redirect("/process/template/list");
		} else {
			// 修改
			String sql = "UPDATE wf_template SET process_name=?,process_type=?,process_des=?,system_module=?,"
					+ "process_version=?,updator=?,update_time=?,catagory = ?,process_prefix=? WHERE process_no=?";
			int result = processTemplateDao.execute(sql,
					new Object[] { processTemplateForm.getProcessName(), processTemplateForm.getProcessType(),
							processTemplateForm.getProcessDes(), processTemplateForm.getSystemModule(),
							processTemplateForm.getProcessVersion(), user.getNo(), new Date(),
							processTemplateForm.getCatagory(), processTemplateForm.getProcessPrefix(),
							processTemplateForm.getProcessNo() });
			if (result > 0) {
				return BaseRestResult.redirect("/wf/template/view?processNo=" + processTemplateForm.getProcessNo());
			} else {
				return BaseRestResult.warn("保存失败!");
			}
		}
	}

	@RequestMapping("/node/template/save")
	public BaseRestResult<String> saveNodeTemplate(ProcessNodeTemplateForm processNodeTemplateForm) {
		try {
			User user = UserHolder.getUser();
			// 添加
			if (StringUtils.isBlank(processNodeTemplateForm.getNodeId())) {
				ProcessNodeTemplate nodeTemplate = new ProcessNodeTemplate();
				try {
					BeanUtils.copyProperties(nodeTemplate, processNodeTemplateForm);
				} catch (Exception e) {
				}
				// 角色审核
				nodeTemplate.setAuditorType(ProcessNodeTemplate.AUDITOR_TYPE_ROLE);
				nodeTemplate.setCreator(user.getNo());
				if (nodeTemplate.getTimeEffective() == null) {
					nodeTemplate.setTimeEffective(0);
				}
				ProcessNodeTemplate saveTemplate = processNodeTemplateDao.insert(nodeTemplate);
				if (saveTemplate != null) {
					templateService.updateTemplateTimeEffective(processNodeTemplateForm.getProcessNo());
					return BaseRestResult
							.redirect("/wf/template/view?processNo=" + processNodeTemplateForm.getProcessNo());
				} else {
					return BaseRestResult.warn("保存失败!");
				}
			} else {
				// 修改
				if (processNodeTemplateForm.getRoleNo().equals("-1")) {
					return BaseRestResult.warn("保存失败，角色不能为空!");
				}
				SysRole sysRole = new SysRole();
				sysRole.setId(processNodeTemplateForm.getRoleNo());
				sysRole = sysPermissionServiceInlet.selectRolesByRole(sysRole).getModel();
				String sql = "UPDATE wf_node_template SET node_name=?,node_code=?,node_desc=?,order_no=?,is_sign=?,is_change=?,is_reject=?,is_pass=?,is_turned_down=?,is_take_back=?,"
						+ "node_type=?,role_no=?,role_name=?,refer_url=?,updator=?,update_time=?,notes_template=?,time_effective=?,"
						+ " is_send_email = ? , is_send_sms = ? ,is_send_wechat = ? ,is_auto_audit = ?,sign_type = ? WHERE node_id=?";
				int result = processTemplateDao.execute(sql,
						new Object[] { processNodeTemplateForm.getNodeName(), processNodeTemplateForm.getNodeCode(),
								processNodeTemplateForm.getNodeDesc(), processNodeTemplateForm.getOrderNo(),
								processNodeTemplateForm.getIsSign(), processNodeTemplateForm.getIsChange(),
								processNodeTemplateForm.getIsReject(), processNodeTemplateForm.getIsPass(),
								processNodeTemplateForm.getIsTurnedDown(), processNodeTemplateForm.getIsTakeBack(),
								processNodeTemplateForm.getNodeType(), processNodeTemplateForm.getRoleNo(),
								sysRole.getRoleName(), processNodeTemplateForm.getReferUrl(), user.getNo(), new Date(),
								processNodeTemplateForm.getNotesTemplate(), processNodeTemplateForm.getTimeEffective(),
								processNodeTemplateForm.getIsSendEmail(), processNodeTemplateForm.getIsSendSms(),
								processNodeTemplateForm.getIsSendWechat(), processNodeTemplateForm.getIsAutoAudit(),
								processNodeTemplateForm.getSignType(), processNodeTemplateForm.getNodeId() });
				if (result > 0) {
					templateService.updateTemplateTimeEffective(processNodeTemplateForm.getProcessNo());
					return BaseRestResult
							.redirect("/wf/template/view?processNo=" + processNodeTemplateForm.getProcessNo());
				} else {
					return BaseRestResult.warn("保存失败!");
				}
			}

		} catch (RuntimeException e) {
			String errMsg = e.getMessage();
			if (StringUtils.isNotBlank(errMsg) && errMsg.indexOf("Duplicate entry") != -1
					&& errMsg.indexOf("for key 'node_code'") != -1) {
				return BaseRestResult.warn("保存失败，节点编码不能重复!");
			}
			return BaseRestResult.warn("保存失败:" + e.getMessage());
		}
	}

	@RequestMapping(value = "/wf/template/isEnable")
	public BaseRestResult<String> isEnable(String processNo, String isEnable) {
		int result = processTemplateDao.updateTemplateStatus(processNo, isEnable);
		if (result > 0) {
			return BaseRestResult.refresh();
		} else {
			return BaseRestResult.warn("修改失败!");
		}
	}

	@RequestMapping("/process/copyTemplate")
	public BaseRestResult<String> copyTemplate(String processNo) {
		boolean result = templateService.copyTemplate(processNo);
		if (result) {
			return BaseRestResult.refresh();
		} else {
			return BaseRestResult.warn("流程复制失败!");
		}
	}

	/**
	 * 流程删除
	 * 
	 * @param processNo
	 * @return
	 */
	@RequestMapping("/wf/process/del")
	public BaseRestResult<String> delProcessTemplate(String processNo) {
		ProcessTemplate processTemplate = processTemplateDao.getById(ProcessTemplate.class, processNo);
		if (processTemplate.getPublishStatus().equals("Y")) {
			return BaseRestResult.warn("流程使用中，不允许删除!");
		}
		int effectRow = processTemplateDao.delProcessTemplate(processNo);
		if (effectRow > 0) {
			return BaseRestResult.refresh();
		} else {
			return BaseRestResult.warn("流程删除失败!");
		}
	}

	@RequestMapping(value = "/act/org/search")
	public BaseRestResult<List<Object[]>> units(String name) {
		List<Object[]> data = new ArrayList<>();
		if (StringUtil.hasText(name)) {
			ModelResult<List<Object[]>> da = sysPermissionServiceInlet.getOrgListLikeName(name,
					ActOrgEntity.ORG_LEVEL_PLATFORM);
			data = da.getModel();
		}
		return BaseRestResult.buildRestResult(data);
	}

	@RequestMapping(value = "/nodeTemplate/del")
	public BaseRestResult<String> delNodeTemplate(String nodeTemplateId, String processNo) {
		if (StringUtils.isBlank(nodeTemplateId)) {
			return BaseRestResult.warn("参数无效!");
		}
		int result = processNodeTemplateDao.delById(nodeTemplateId);
		if (result > 0) {
			templateService.updateTemplateTimeEffective(processNo);
			return BaseRestResult.refresh();
		} else {
			return BaseRestResult.warn("修改失败!");
		}
	}
	
	
	@RequestMapping(value = "/updateTaskNodeStartDate")
	public BaseRestResult<String> updateTaskNodeStartDate() {
		wfQueryService.updateTaskNodeStartDate();
		return BaseRestResult.info("修改成功!");
	}
}
